Skip to content

Allow stripping setup/ from production deploy artifacts (#40695)#40793

Open
lbajsarowicz wants to merge 1 commit into
magento:2.4-developfrom
lbajsarowicz:feature/issue-40695-deploy-ignore-setup
Open

Allow stripping setup/ from production deploy artifacts (#40695)#40793
lbajsarowicz wants to merge 1 commit into
magento:2.4-developfrom
lbajsarowicz:feature/issue-40695-deploy-ignore-setup

Conversation

@lbajsarowicz
Copy link
Copy Markdown
Contributor

@lbajsarowicz lbajsarowicz commented Apr 29, 2026

Description

Closes #40695 (partially — composer-side enabler).

The setup/ directory is a 568-file Laminas MVC application originally built for the deprecated web Setup Wizard. It is currently a hard runtime dependency for bin/magento. This PR is the smallest possible composer-layer change that lets a deployment pipeline strip setup/ from a runtime artifact without breaking the Magento\Setup\* namespace lookup that other CLI tooling still needs.

Changes

  1. extra.magento-deploy-ignore — declares /setup, /update, /pub/errors, /.gitignore as paths that may be removed from a production deploy artifact. Honored by magento/magento-composer-installer at deploy time.
  2. autoload.psr-4 fallback for Magento\\Setup\\ — array form: primary path stays setup/src/Magento/Setup/ (unchanged for local dev / source repo), secondary path vendor/magento/magento2-base/setup/src/Magento/Setup/ is resolved when the deploy-ignore step has removed the repository-root copy. Composer merges array entries; existing dev installs are unaffected.

Why this approach

Full discussion in #40695. This PR intentionally does not:

  • move classes between namespaces (would break @api BC),
  • modify Magento\Framework\Console\Cli,
  • change app/etc/di.xml preferences,
  • delete deprecated Laminas listeners.

Those are tracked in the issue as larger follow-ups requiring code review and benchmarks. This PR ships only the composer-manifest scaffolding so downstream pipelines can opt into stripping setup/ today.

Verification

$ composer dump-autoload -o
Generating optimized autoload files
Generated optimized autoload files containing 26959 classes

$ php -r 'require "vendor/autoload.php"; var_dump(class_exists("Magento\\Setup\\Console\\Command\\InstallCommand"));'
bool(true)

JSON syntax validated.

Backward Compatibility

  • Local autoload unchanged (primary psr-4 path is identical).
  • magento-deploy-ignore is opt-in; no existing deployment is affected unless tooling actively reads it.
  • No public API changes.

Manual testing instructions

  1. composer install
  2. composer dump-autoload -o
  3. Run bin/magento list — must work.
  4. (Downstream pipelines): after build, remove setup/ and update/ per magento-deploy-ignore; runtime CLI commands that depend on Magento\Setup\* continue resolving via vendor copy of magento/magento2-base.

Follow-up scope (out of this PR)

  • Guard Cli.php:97 require BP . '/setup/config/application.config.php' with file_exists (issue Remove setup/ directory dependency from production artifacts #40695).
  • Provide framework-owned implementations of SchemaSetupInterface / ModuleDataSetupInterface so the repository-root setup/ is not required even when vendor/magento/magento2-base/setup/ is also absent.
  • Decouple AbstractSetupCommand from the deprecated Magento\Setup\Mvc\Bootstrap\InitParamListener.

Related

@m2-assistant
Copy link
Copy Markdown

m2-assistant Bot commented Apr 29, 2026

Hi @lbajsarowicz. Thank you for your contribution!
Here are some useful tips on how you can test your changes using Magento test environment.
❗ Automated tests can be triggered manually with an appropriate comment:

  • @magento run all tests - run or re-run all required tests against the PR changes
  • @magento run <test-build(s)> - run or re-run specific test build(s)
    For example: @magento run Unit Tests

<test-build(s)> is a comma-separated list of build names.

Allowed build names are:
  1. Database Compare
  2. Functional Tests CE
  3. Functional Tests EE
  4. Functional Tests B2B
  5. Integration Tests
  6. Magento Health Index
  7. Sample Data Tests CE
  8. Sample Data Tests EE
  9. Sample Data Tests B2B
  10. Static Tests
  11. Unit Tests
  12. WebAPI Tests
  13. Semantic Version Checker

You can find more information about the builds here
ℹ️ Run only required test builds during development. Run all test builds before sending your pull request for review.


For more details, review the Code Contributions documentation.
Join Magento Community Engineering Slack and ask your questions in #github channel.

@lbajsarowicz
Copy link
Copy Markdown
Contributor Author

Why deploy-ignore instead of removing setup/ from magento/magento2-base extra.map?

Cleaner long-term destination is removing setup/ from the magento/magento2-base package map entirely — the file never lands in project root, no deploy-time strip needed. This PR deliberately does not do that. Reasoning:

  1. Source-of-truth lives outside this repository. magento/magento2-base composer.json (and its extra.map listing every file copied into project root) is generated by the Adobe release pipeline from a subtree split. There is no publication tooling under dev/build/ in this tree to PR against.

  2. Map removal is unconditional. Every install loses setup/ at project root immediately. Today that breaks bin/magento for every command because:

    • Magento\Framework\Console\Cli.php:97 unconditionally requires BP . '/setup/config/application.config.php'.
    • app/etc/di.xml resolves Magento\Framework\Setup\SchemaSetupInterface and ModuleDataSetupInterface to Magento\Setup\Module\Setup / DataSetup.
    • Magento\Backend maintenance commands extend Magento\Setup\Console\Command\AbstractSetupCommand, which depends on Magento\Setup\Mvc\Bootstrap\InitParamListener (annotated @deprecated).

    Map removal without these fixes = hard breakage for every downstream install.

  3. magento-deploy-ignore is opt-in and BC-safe. Projects that want the leaner artifact set the deploy step; everyone else is unaffected. Zero forced behavior change.

  4. Vendor copy still ships. vendor/magento/magento2-base/setup/src/Magento/Setup/ continues to exist for class resolution after the project-root copy is stripped — covered by the autoload fallback added in this PR.

Sequencing

  1. This PR — composer-layer enabler. Opt-in deploy-ignore + autoload fallback. No code-path change.
  2. Follow-up (issue Remove setup/ directory dependency from production artifacts #40695) — guard Cli.php:97 with file_exists, provide framework-owned implementations of the runtime setup interfaces, decouple AbstractSetupCommand from the deprecated Mvc\Bootstrap listener. Keep Magento\Setup\* runtime classes as class_alias BC shims.
  3. After (1) + (2) ship — Adobe release pipeline can drop setup/ from magento2-base extra.map. At that point it is a pure packaging change with no runtime risk because the code path no longer requires the project-root copy.

The map change is the destination. magento-deploy-ignore + Cli.php guard are the prerequisites that make the destination safe.

@hostep
Copy link
Copy Markdown
Contributor

hostep commented Apr 29, 2026

And what's the point for removing /setup during production build, even if the exact same directory still live in vendor/magento/magento2-base/setup? As in, what are you trying to accomplish exactly here?

Also - and this is very specific - at our agency, we already completely delete vendor/magento/magento2-base during production builds after the initial composer install, as this directory serves 0 purpose in a production environment. So this proposed change would break our flows as the autoload will point to a directory that's not even there anymore (I admit that this is very specific to how we work in our agency, but other people may do similar things).

Also why not deploy /pub/errors? Those files are very useful in a production environment.

Also, why is /update mentioned there? As far as I remember it, it was removed in Magento 2.4.0 and higher, no?

@lbajsarowicz
Copy link
Copy Markdown
Contributor Author

lbajsarowicz commented Apr 29, 2026

@hostep

And what's the point for removing /setup during production build

I believe that beginner agencies expose their Clients at additional, unnecessary risks...

Since Magento removed Web Install, the setup/ directory serves no purpose.

Also why not deploy /pub/errors? Those files are very useful in a production environment.

That's just accidental change pushed along other.

Issue magento#40695

- Add `magento-deploy-ignore` extra so deployment artifacts can strip
  /setup and /update directories (web Setup Wizard is deprecated;
  shipping it to production web nodes is unnecessary attack surface).
- Add fallback autoload path to vendor/magento/magento2-base/setup/
  for the Magento\Setup\* namespace so CLI tooling that still needs
  setup classes keeps resolving when the repository copy is stripped
  by the deploy-ignore step.

Local development resolution is unchanged: setup/src/Magento/Setup/
remains the primary path. Verified `composer dump-autoload -o`
generates 26959 classes and Magento\Setup\Console\Command\* loads.
@lbajsarowicz lbajsarowicz force-pushed the feature/issue-40695-deploy-ignore-setup branch from 36a914a to 139c8eb Compare April 29, 2026 21:38
@hostep
Copy link
Copy Markdown
Contributor

hostep commented Apr 29, 2026

Those 3 examples you give may be beginners indeed, but mostly is a misconfigured webserver which is not using pub as docroot, that's the true issue here.

magento-deploy-ignore is opt-in; no existing deployment is affected unless tooling actively reads it.

also, If those are beginners, why would they ever opt-in into this then? I mean, it won't solve anything for beginners if this is optional.

But nevertheless, I agree that the setup directory should get refactored and eventually removed entirely from the codebase, but how it's done in this PR makes no sense in my opinion. We should do this without such strange workarounds, but instead doing it properly in the first place.

And if a quick fix is really needed first, just delete the file setup/index.php, that's a much better solution in my opinion.
Update: doesn't this change already solve this: #39228? (it will be included in Magento 2.4.9) - for hosters with nginx webservers, it will require them to setup the correct nginx config though, but for apache users it should work automatically.

@lbajsarowicz
Copy link
Copy Markdown
Contributor Author

@hostep Maybe we should also remove index.php from the root directory... Not only allowing to remove setup/ and magento2-base 👿

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Priority: P3 May be fixed according to the position in the backlog. Progress: pending review

Projects

Status: Pending Review

Development

Successfully merging this pull request may close these issues.

Remove setup/ directory dependency from production artifacts

3 participants